<template>
  <div class="page-container">
    <div class="in-container">
      <el-row :gutter="8">
        <el-col :span="4">
          <el-card>
            <template #header>
              <div class="card-header">
                <span>个人信息</span>
              </div>
            </template>
            <div style="display: flex; justify-content: center">
              <el-upload
                class="avatar-uploader"
                action="/api/user/update/avatar"
                :show-file-list="false"
                :on-success="handleAvatarSuccess"
                :on-error="handleAvatarError"
                :class="state.userInfo.avatarPath ? 'unborder' : ''"
                :headers="{ Authorization: token }"
                name="avatar"
              >
                <el-avatar
                  :size="120"
                  :src="state.userInfo.avatarPath"
                  fit="cover"
                  v-if="state.userInfo.avatarPath"
                />
                <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
              </el-upload>
            </div>
            <ul class="user-info">
              <li>
                登录账号
                <div class="user-right">{{ state.userInfo.username }}</div>
              </li>
              <li>
                用户昵称
                <div class="user-right">{{ state.userInfo.nickName }}</div>
              </li>
              <li>
                所属部门
                <div class="user-right">{{ state.userInfo.dept.name }}</div>
              </li>
              <li>
                手机号码
                <div class="user-right">{{ state.userInfo.phone }}</div>
              </li>
              <li>
                用户邮箱
                <div class="user-right">{{ state.userInfo.email }}</div>
              </li>
              <li>
                安全设置
                <div class="user-right">
                  <a @click="state.passwordDialog.show = true">修改密码</a>
                  <a @click="openUpdateEmail">修改邮箱</a>
                </div>
              </li>
            </ul>
          </el-card>
        </el-col>
        <el-col :span="20">
          <el-card>
            <template #header>
              <div class="card-header">
                <span>个人信息编辑</span>
              </div>
            </template>
            <div>
              <el-form
                :model="userForm"
                style="max-width: 460px"
                label-width="70px"
                :rules="userFormRule"
              >
                <el-form-item prop="nickName" label="昵称">
                  <el-input v-model="state.userForm.nickName"> </el-input>
                </el-form-item>
                <el-form-item prop="realname" label="姓名">
                  <el-input v-model="state.userForm.realname"> </el-input>
                </el-form-item>
                <el-form-item prop="phone" label="手机">
                  <el-input v-model="state.userForm.phone"> </el-input>
                </el-form-item>
                <el-form-item prop="phoneNumber" label="座机">
                  <el-input v-model="state.userForm.phoneNumber"> </el-input>
                </el-form-item>
                <el-form-item prop="qq" label="QQ">
                  <el-input v-model="state.userForm.qq"> </el-input>
                </el-form-item>

                <el-form-item prop="gender" label="性别">
                  <el-radio-group v-model="state.userForm.gender">
                    <el-radio label="男">男</el-radio>
                    <el-radio label="女">女</el-radio>
                  </el-radio-group>
                </el-form-item>
                <el-form-item>
                  <el-button @click="submitUserInfo" type="primary">
                    保存
                  </el-button>
                </el-form-item>
              </el-form>
            </div>
          </el-card>
        </el-col>
      </el-row>
    </div>
  </div>
  <el-dialog v-model="state.passwordDialog.show" title="修改密码" width="500px">
    <el-form
      ref="passwordForm"
      :model="state.passwordDialog.form"
      :rules="state.passwordDialog.formRules"
      size="small"
      label-width="100px"
    >
      <el-form-item label="旧密码" prop="oldPassword">
        <el-input
          v-model="state.passwordDialog.form.oldPassword"
          type="password"
        />
      </el-form-item>
      <el-form-item label="新密码" prop="newPassword">
        <el-input
          v-model="state.passwordDialog.form.newPassword"
          type="password"
        />
      </el-form-item>
      <el-form-item label="确认密码" prop="confirmPassword">
        <el-input
          v-model="state.passwordDialog.form.confirmPassword"
          type="password"
        />
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="cancelPwd" link>取消</el-button>
        <el-button type="primary" @click="submitPwd"> 确认 </el-button>
      </span>
    </template>
  </el-dialog>
  <el-dialog v-model="state.emailDialog.show" title="修改邮箱" width="500px">
    <el-form
      ref="emailForm"
      :model="state.emailDialog.form"
      :rules="state.emailDialog.formRules"
      size="small"
      label-width="88px"
    >
      <el-form-item label="新邮箱" prop="email" class="el-form-button">
        <el-input style="width: 254px;" class="emailInput" v-model="state.emailDialog.form.email" />
        <el-button
          :loading="state.codeLoading"
          :disabled="state.codeDisabled"
          size="small"
          @click="getEmailCode"
          type="primary"
          >{{ state.codeButtonName }}</el-button
        >
      </el-form-item>
      <el-form-item label="验证码" prop="code">
        <el-input v-model="state.emailDialog.form.code" />
      </el-form-item>
      <el-form-item label="当前密码" prop="password">
        <el-input v-model="state.emailDialog.form.password" type="password" />
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="cancelEmail" link>取消</el-button>
        <el-button type="primary" @click="submitEmail"> 确认 </el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script setup>
import { ref, reactive, onMounted, watch, nextTick } from "vue";
import { isvalidPhone, validEmail } from "@/utils/validate";
import { encrypt } from "@/utils/rsaEncrypt";
import { useStore } from "vuex";
import { useRouter, useRoute } from "vue-router";
import { ElMessage } from "element-plus";
import request from "@/public/request";

const Store = useStore();
const Route = useRoute();
const Router = useRouter();
// 密码校验
const confirmPass = (rule, value, callback) => {
  if (value) {
    if (state.passwordDialog.form.newPassword !== value) {
      callback(new Error("两次输入的密码不一致"));
    } else {
      callback();
    }
  } else {
    callback(new Error("请再次输入密码"));
  }
};
// 邮箱校验
const validMail = (rule, value, callback) => {
  if (value === "" || value === null) {
    callback(new Error("新邮箱不能为空"));
  } else if (value === state.email) {
    callback(new Error("新邮箱不能与旧邮箱相同"));
  } else if (validEmail(value)) {
    callback();
  } else {
    callback(new Error("邮箱格式错误"));
  }
};
// 手机号校验
const validPhone = (rule, value, callback) => {
  if (!value) {
    callback(new Error("请输入电话号码"));
  } else if (!isvalidPhone(value)) {
    callback(new Error("请输入正确的11位手机号码"));
  } else {
    callback();
  }
};
const state = reactive({
  userInfo: {
    dept: {
      name: "",
    },
  },
  userForm: {
    id: 0,
    nickName: "",
    phone: "",
    phoneNumber: "",
    qq: "",
    realname: "",
    gender: "男",
  },
  userFormRule: {
    nickName: [{ required: true, message: "请输入昵称", trigger: "change" }],
    phone: [{ required: true, validator: validPhone, trigger: "change" }],
    realname: [
      { required: true, message: "请输入真实姓名", trigger: "change" },
    ],
  },
  passwordDialog: {
    show: false,
    loading: false,
    form: {
      oldPassword: "",
      newPassword: "",
      confirmPassword: "",
    },
    formRules: {
      oldPassword: [
        { required: true, message: "请输入旧密码", trigger: "blur" },
      ],
      newPassword: [
        { required: true, message: "请输入新密码", trigger: "blur" },
        {
          min: 6,
          max: 20,
          message: "长度在 6 到 20 个字符",
          trigger: "blur",
        },
      ],
      confirmPassword: [
        { required: true, validator: confirmPass, trigger: "blur" },
      ],
    },
  },
  emailDialog: {
    show: false,
    loading: false,
    btnLoading: false,
    form: {
      password: "",
      email: "",
      code: "",
    },
    formRules: {
      password: [
        { required: true, message: "当前密码不能为空", trigger: "blur" },
      ],
      email: [{ required: true, validator: validMail, trigger: "blur" }],
      code: [{ required: true, message: "验证码不能为空", trigger: "blur" }],
    },
  },
  codeButtonName: "发送验证码",
  codeLoading: false,
  codeDisabled: false,
  timer: null,
  token: localStorage.getItem("jst:token"),
});
// 获取用户信息
const getUserInfo = async () => {
  try {
    let res = await request.get("/auth/info");
    state.userInfo = res.user;
    state.userInfo.avatarPath =
      import.meta.env.VITE_APP_HOST + state.userInfo.avatarPath;
    state.userForm.id = res.user.id;
    state.userForm.nickName = res.user.nickName;
    state.userForm.phone = res.user.phone;
    state.userForm.phoneNumber = res.user.phoneNumber;
    state.userForm.qq = res.user.qq;
    state.userForm.realname = res.user.realName;
    state.userForm.gender = res.user.gender;
  } catch (error) {
    ElMessage.error("获取个人资料失败");
  }
};
// 提交用户信息
const submitUserInfo = async () => {
  let res = await request.post("/api/user/center", state.userForm);
  if (res.status) {
    ElMessage.success(res.message);
    getUserInfo();
  } else {
    ElMessage.error(res.message);
  }
};
// 打开新邮箱绑定
const openUpdateEmail = () => {
  state.emailDialog.show = true;
};
const emailForm = ref();
const passwordForm = ref();
// 获取邮箱验证码
const getEmailCode = () => {
  emailForm.value.validateField("email", async (vaild) => {
    if (vaild == "") {
      let url = "auth/code/reset/email?email=" + state.emailDialog.form.email;
      state.codeLoading = true;
      try {
        let res = await request.post(url);
        if (res.status) {
          ElMessage.success("验证码发送成功，5分钟内有效");
          state.codeDisabled = true;
          startCountdown();
        } else {
          ElMessage.error(res.message ?? "获取错误");
        }
      } catch (error) {}
      state.codeLoading = false;
    }
  });
};
// 验证码倒计时
const startCountdown = () => {
  if (state.timer) {
    clearInterval(state.timer);
  }
  let countdown = 60;
  state.timer = setInterval(() => {
    if (countdown > 0) {
      countdown--;
      state.codeButtonName = countdown + "s";
    } else {
      state.codeDisabled = false;
      clearInterval(state.timer);
      state.timer = null;
      state.codeButtonName = "发送验证码";
    }
  }, 1000);
};
// 关闭邮箱弹窗
const cancelEmail = () => {
  state.emailDialog.show = false;
};
// 提交更新邮箱
const submitEmail = async () => {
  state.emailDialog.form.password = encrypt(state.emailDialog.form.password);
  let res = await request.post(
    "/api/user/update/email",
    state.emailDialog.form
  );
  if (res.status) {
    ElMessage.success(res.message);
    state.emailDialog.show = false;
    getUserInfo();
  } else {
    ElMessage.error(res.message ?? "获取错误");
  }
};
// 关闭密码弹窗
const cancelPwd = () => {
  state.passwordDialog.show = false;
};
// 提交更新密码
const submitPwd = async () => {
  state.passwordDialog.form.oldPassword = encrypt(
    state.passwordDialog.form.oldPassword
  );
  state.passwordDialog.form.newPassword = encrypt(
    state.passwordDialog.form.newPassword
  );
  state.passwordDialog.form.confirmPassword = encrypt(
    state.passwordDialog.form.confirmPassword
  );

  let res = await request.post(
    "/api/user/update/password",
    state.passwordDialog.form
  );

  if (res.status) {
    ElMessage.success(res.message);
    state.passwordDialog.show = false;
  } else {
    ElMessage.error(res.message ?? "获取错误");
    state.emailDialog.form = {
      password: "",
      email: "",
      code: "",
    };
  }
};
// 成功反馈
const handleAvatarSuccess = (res) => {
  if (res.status) {
    ElMessage.success("上传成功");
    getUserInfo();
  } else {
    ElMessage.error(res.message ?? "上传失败");
  }
};
// 失败反馈
const handleAvatarError = () => {
  ElMessage.error("上传失败");
};
// 监听数据
watch(state.emailDialog.show, (newVal, oldCal) => {
  if (!newVal) {
    state.emailDialog.form = {
      password: "",
      email: "",
      code: "",
    };
    nextTick(() => {
      emailForm.value.clearValidate();
    });
  }
});
watch(state.passwordDialog.show, (newVal, oldCal) => {
  if (!newVal) {
    state.passwordDialog.form = {
      oldPassword: "",
      newPassword: "",
      confirmPassword: "",
    };
    nextTick(() => {
      passwordForm.value.clearValidate();
    });
  }
});

onMounted(() => {
  getUserInfo();
});
</script>

<style lang="scss" scoped>
:deep(.el-avatar) > img {
  width: 100%;
}

.user-info {
  padding-left: 0;
  list-style: none;
  li {
    border-bottom: 1px solid #f0f3f4;
    padding: 11px 0;
    font-size: 13px;
  }
  .user-right {
    float: right;
    a {
      color: #317ef3;
      cursor: pointer;
    }
    a:last-child {
      margin-left: 8px;
    }
  }
}

.el-form-button {
  :deep(.el-form-item__content) {
    display: flex;
    .el-button {
      margin-left: 8px;
    }
  }
}
.avatar-uploader {
  width: 120px;
  height: 120px;
  :deep(.el-upload) {
    width: 100%;
    height: 100%;
    border: 1px dashed #dcdfe6;
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    transition: 0.2s;
    display: inline-flex;
    justify-content: center;
    align-items: center;
    outline: none;
    .el-icon {
      font-size: 28px;
      color: #8c939d;
      width: 100%;
      height: 100%;
      text-align: center;
      display: inline-flex;
      justify-content: center;
      align-items: center;
    }
  }
}

.unborder {
  :deep(.el-upload) {
    border: 0px;
    cursor: pointer;
  }
}
.emailInput {
  width: 280px;
}
</style>
